package com.quiz.bis.template.pdf;

import com.quiz.bis.domain.bo.QuestionExportBo;
import com.quiz.bis.domain.model.QuestionAnswer;
import com.quiz.bis.domain.model.QuestionOption;
import com.quiz.bis.domain.vo.QuestionDetailVo;
import com.quiz.bis.domain.vo.QuestionExportVo;
import com.quiz.file.domain.model.FileInfo;
import com.quiz.file.service.IFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.parser.Tag;
import org.jsoup.select.Elements;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.scilab.forge.jlatexmath.TeXIcon;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.file.Files;
import java.util.Base64;
import java.util.List;

/**
 * 题目html模版
 * </p>
 * 用于 PDF导出
 *
 * @author ahuan
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class QuestionHTML {

    private final IFileService fileService;

    @SuppressWarnings("all")
    public String builder(List<QuestionExportVo> questions, HttpServletRequest request, QuestionExportBo query) {
        // 构建HTML内容
        StringBuilder htmlBuilder = new StringBuilder();
        htmlBuilder.append("<!DOCTYPE html>");
        htmlBuilder.append("<html>");
        htmlBuilder.append("<head>");
        htmlBuilder.append("<meta charset=\"UTF-8\"/>");
        processStyle(htmlBuilder);
        htmlBuilder.append("</head>");
        processBody(htmlBuilder, questions, request, query);
        htmlBuilder.append("</html>");
        return htmlBuilder.toString();
    }

    // 处理style
    private void processStyle(StringBuilder htmlBuilder) {
        htmlBuilder.append("<style>")
                .append("body { font-family: SimSun; }")
//                .append(".editor-content-view { border: 3px solid #ccc; border-radius: 5px; padding: 0 10px; margin-top: 20px; overflow-x: auto; }")
                // 修改为更柔和的边框
                .append(".editor-content-view { ")
                .append("  border: 1px solid #eee; ") // 更细更浅的边框
                .append("  border-radius: 3px; ")    // 更小的圆角
                .append("  padding: 10px; ")         // 增加内边距
                .append("  margin: 15px 0; ")        // 调整外边距
                .append("  box-shadow: 0 1px 3px rgba(0,0,0,0.1); ") // 可选：添加轻微阴影
                .append("}")
                .append(".editor-content-view p, .editor-content-view li { white-space: pre-wrap; }")
                .append(".editor-content-view blockquote { border-left: 8px solid #d0e5f2; padding: 10px; margin: 10px 0; background-color: #f1f1f1; }")
                .append(".editor-content-view code { font-family: monospace; background-color: #eee; padding: 3px; border-radius: 3px; }")
                .append(".editor-content-view pre>code { display: block; padding: 10px; }")
                .append(".editor-content-view table { border-collapse: collapse; }")
                .append(".editor-content-view td, .editor-content-view th { border: 1px solid #ccc; min-width: 50px; height: 20px; }")
                .append(".editor-content-view th { background-color: #f1f1f1; }")
                .append(".editor-content-view ul, .editor-content-view ol { padding-left: 20px; }")
                .append("</style>");
    }

    // 处理body
    private void processBody(StringBuilder htmlBuilder, List<QuestionExportVo> questions, HttpServletRequest request, QuestionExportBo query) {
        htmlBuilder.append("<body>");
        for (QuestionExportVo questionType : questions) {
            htmlBuilder.append("<h2>").append(questionType.getTypeName()).append("</h2>");
            for (QuestionDetailVo question : questionType.getQuestions()) {
                htmlBuilder.append("<div class='editor-content-view'>");
                // 题目标题（纯文本）
                htmlBuilder.append("<h3>").append(escapeHtml(question.getTitle())).append("</h3>");
                // 题目内容（HTML）
                htmlBuilder.append(processHtmlContent(question.getContent(), request));
                // 选项
                if (question.getOptions() != null && !question.getOptions().isEmpty()) {
                    htmlBuilder.append("<h4>选项</h4>").append(processOptions(question.getOptions(), request));
                }
                // 答案
                if (Boolean.TRUE.equals(query.getIncludeAnswer())) {
                    htmlBuilder.append("<h4>答案</h4>").append(processAnswers(question.getAnswers(), request));
                }
                // 解析
                if (Boolean.TRUE.equals(query.getIncludeAnalysis())) {
                    htmlBuilder.append("<h4>解析</h4>").append(processHtmlContent(question.getAnalysis(), request));
                }
                htmlBuilder.append("</div>");
            }
        }

        htmlBuilder.append("</body>");
    }


    // 处理选项列表
    private String processOptions(List<QuestionOption> options, HttpServletRequest request) {
        if (options == null || options.isEmpty()) return "";
        StringBuilder sb = new StringBuilder("<ul>");
        for (QuestionOption option : options) {
            sb.append("<li>")
                    .append(processHtmlContent(option.getContent(), request))
                    .append("</li>");
        }
        sb.append("</ul>");
        return sb.toString();
    }

    // 处理答案列表
    private String processAnswers(List<QuestionAnswer> answers, HttpServletRequest request) {
        if (answers == null || answers.isEmpty()) return "";
        StringBuilder sb = new StringBuilder();
        for (QuestionAnswer answer : answers) {
            sb.append(processHtmlContent(answer.getContent(), request));
        }
        return sb.toString();
    }

    // 处理HTML内容
    private String processHtmlContent(String html, HttpServletRequest request) {
        if (html == null || html.isEmpty()) return "";

        Document doc = Jsoup.parseBodyFragment(html);
        Element body = doc.body();

        // 处理数学公式
        processFormulas(body);

        // 处理图片
        processImages(body, request);

        return body.html();
    }

    private void processImages(Element body, HttpServletRequest request) {
        Elements imgElements = body.select("img");
        for (Element img : imgElements) {
            String src = img.attr("src");
            if (src.startsWith("data:")) {
                // 已经是base64数据，不需要处理
                continue;
            }

            // 从URL中提取文件ID
            String fileId = extractFileIdFromUrl(src);
            if (fileId != null) {
                try {
                    // 获取文件并转换为base64
                    FileInfo fileInfo = fileService.getFileById(Long.parseLong(fileId));
                    File file = new File(fileInfo.getFilePath());
                    byte[] fileContent = Files.readAllBytes(file.toPath());
                    String base64 = Base64.getEncoder().encodeToString(fileContent);
                    String mimeType = Files.probeContentType(file.toPath());

                    img.attr("src", "data:" + mimeType + ";base64," + base64)
                            .attr("style", "max-width: 100%; height: auto; display: block; margin: 5px auto;");
                } catch (Exception e) {
                    img.attr("src", "")
                            .attr("alt", "[图片加载失败: " + fileId + "]");
                }
            }
        }
    }

    private String extractFileIdFromUrl(String url) {
        // 匹配类似1915099229114634242这样的数字ID
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("/(\\d+)(\\?|$)");
        java.util.regex.Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }

    // 处理数学公式
    private void processFormulas(Element body) {
        Elements formulaElements = body.select("span[data-w-e-type=formula]");
        for (Element element : formulaElements) {
            String latex = element.attr("data-value");
            try {
                byte[] imageData = renderLatexToImage(latex);
                String base64 = Base64.getEncoder().encodeToString(imageData);
                // 创建img标签(上面这种是面向html5的，为了兼容性，不要使用非闭合标签)
//                Element img = new Element("img")
//                        .attr("src", "data:image/png;base64," + base64)
//                        .attr("style", "vertical-align: middle;");
                Element img = new Element(Tag.valueOf("img"), "")  // 强制生成闭合标签
                        .attr("src", "data:image/png;base64," + base64)
                        .attr("style", "vertical-align: middle;");
                element.replaceWith(img);
            } catch (Exception e) {
                element.replaceWith(new TextNode("[公式渲染错误]"));
            }
        }
    }

    // 渲染LaTeX为图片
    private byte[] renderLatexToImage(String latex) throws Exception {
        TeXFormula formula = new TeXFormula(latex);
        TeXIcon icon = formula.createTeXIcon(TeXConstants.STYLE_TEXT, 16);
        icon.setInsets(new Insets(2, 2, 2, 2));

        BufferedImage image = new BufferedImage(
                icon.getIconWidth(),
                icon.getIconHeight(),
                BufferedImage.TYPE_INT_ARGB
        );
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        icon.paintIcon(null, g2, 0, 0);
        g2.dispose();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", baos);
        return baos.toByteArray();
    }

    // 获取图片访问地址（需根据业务实现）
    private String getImageUrl(String fileId, HttpServletRequest request) {
        // 示例实现，应替换为真实URL获取逻辑
        return "https://your-file-service/" + fileId;
    }

    // HTML转义
    private String escapeHtml(String text) {
        if (text == null) return "";
        return text.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#39;");
    }

}
